/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bio.jpa.entities;

import com.bio.jsf.FastaController;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Diego
 */
@Entity
@Table(name = "fasta")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Fasta.findAll", query = "SELECT f FROM Fasta f"),
    @NamedQuery(name = "Fasta.findByFastaId", query = "SELECT f FROM Fasta f WHERE f.fastaId = :fastaId"),
    @NamedQuery(name = "Fasta.findByDefline", query = "SELECT f FROM Fasta f WHERE f.defline = :defline"),
    @NamedQuery(name = "Fasta.findByCreationDate", query = "SELECT f FROM Fasta f WHERE f.creationDate = :creationDate")})
public class Fasta implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Basic(optional = false)
    @Column(name = "fasta_id")
    private Integer fastaId;
    @Size(max = 200)
    @Column(name = "defline")
    private String defline;
    @Basic(optional = false)
    @NotNull
    @Column(name = "creation_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate;
    @JoinColumn(name = "created_by", referencedColumnName = "user_id")
    @ManyToOne
    private User createdBy;
    @JoinColumn(name = "project_id", referencedColumnName = "prj_id")
    @ManyToOne(optional = false)
    private Project project;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "fasta")
    private List<FastaSequence> fastaSequenceList = new ArrayList<FastaSequence>();
    @Transient
    private String allSequence="";

    private String listToString(List<FastaSequence> list) {
        if (list != null) {
            StringBuilder sb = new StringBuilder(list.size() * 80);
            for (FastaSequence f : list) {
                sb.append(f.getSeq());
            }
            allSequence = sb.toString();
            sb.setLength(0);
        }
        return allSequence;
    }

    public String getAllSequence() {
        allSequence = listToString(fastaSequenceList).trim();
        return allSequence;
    }

    public void setAllSequence(String allSequence) {
        fastaSequenceList = stringToList(allSequence.trim());
        this.allSequence = allSequence;
    }

    private List<FastaSequence> stringToList(String allSequence) {
        StringReader sr = new StringReader(allSequence);
        List<FastaSequence> list = new ArrayList<FastaSequence>();
        int reads = 0;
        int buffer = 60 * 200;
        char[] buf = new char[buffer];
        int pos = 1;
        try {
            while ((reads = sr.read(buf)) != -1) {
                list.add(new FastaSequence(String.valueOf(buf, 0, reads), pos, this));
                pos = buffer + pos;
            }
        } catch (IOException ex) {
            Logger.getLogger(FastaController.class.getName()).log(Level.SEVERE, null, ex);
        }
        return list;
    }

    public Fasta() {
    }

    public Fasta(Integer fastaId) {
        this.fastaId = fastaId;
    }

    public Fasta(Integer fastaId, Date creationDate) {
        this.fastaId = fastaId;
        this.creationDate = creationDate;
    }

    public Integer getFastaId() {
        return fastaId;
    }

    public void setFastaId(Integer fastaId) {
        this.fastaId = fastaId;
    }

    public String getDefline() {
        return defline;
    }

    public void setDefline(String defline) {
        this.defline = defline;
    }

    public Date getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    public User getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(User createdBy) {
        this.createdBy = createdBy;
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    @XmlTransient
    public List<FastaSequence> getFastaSequenceList() {
        stringToList(allSequence);
        return fastaSequenceList;
    }

    public void setFastaSequenceList(List<FastaSequence> fastaSequenceList) {
        this.fastaSequenceList = fastaSequenceList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (fastaId != null ? fastaId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Fasta)) {
            return false;
        }
        Fasta other = (Fasta) object;
        if ((this.fastaId == null && other.fastaId != null) || (this.fastaId != null && !this.fastaId.equals(other.fastaId))) {
            return false;
        }
        if ((this.defline == null && other.defline != null) || (this.defline != null && !this.defline.equals(other.defline))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.bio.jpa.entities.Fasta[ fastaId=" + fastaId + " ]";
    }
}
